using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace donet {
    /// <summary>
    /// ftp文件上传、下载操作类
    /// </summary>
    public class FTPHelper {

        /// <summary>
        /// ftp用户名，匿名为“”
        /// </summary>
        private string ftpUser;

        /// <summary>
        /// ftp用户密码，匿名为“”
        /// </summary>
        private string ftpPassWord;

        private string ftpHost;

        /// <summary>
        ///通过用户名，密码连接到FTP服务器
        /// </summary>
        /// <param name="ftpUser">ftp用户名，匿名为“”</param>
        /// <param name="ftpUser">ftp用户名，匿名为“”</param>
        /// <param name="ftpPassWord">ftp登陆密码，匿名为“”</param>
        public FTPHelper (string ftpHost, string ftpUser, string ftpPassWord) {
            this.ftpHost = ftpHost;
            this.ftpUser = ftpUser;
            this.ftpPassWord = ftpPassWord;
        }

        /// <summary>
        /// 匿名访问
        /// </summary>
        public FTPHelper () {
            this.ftpUser = "";
            this.ftpPassWord = "";
        }

        /// <summary>
        /// 上传文件到Ftp服务器
        /// </summary>
        /// <param name="uri">把上传的文件保存为ftp服务器文件的uri,如"/capture-212.avi"</param>
        /// <param name="upLoadFile">要上传的本地的文件路径，如D:\capture-2.avi</param>
        public void UpLoadFile (string UpLoadUri, string upLoadFile) {
            Stream requestStream = null;
            FileStream fileStream = null;
            FtpWebResponse uploadResponse = null;

            try {
                Uri uri = new Uri ("ftp://" + ftpHost + UpLoadUri);

                FtpWebRequest uploadRequest = (FtpWebRequest) WebRequest.Create (uri);
                uploadRequest.Method = WebRequestMethods.Ftp.UploadFile;

                uploadRequest.Credentials = new NetworkCredential (ftpUser, ftpPassWord);

                requestStream = uploadRequest.GetRequestStream ();
                fileStream = File.Open (upLoadFile, FileMode.Open);

                byte[] buffer = new byte[1024];
                int bytesRead;
                while (true) {
                    bytesRead = fileStream.Read (buffer, 0, buffer.Length);
                    if (bytesRead == 0)
                        break;
                    requestStream.Write (buffer, 0, bytesRead);
                }

                requestStream.Close ();

                uploadResponse = (FtpWebResponse) uploadRequest.GetResponse ();

            } catch (Exception ex) {
                throw new Exception ("上传文件到ftp服务器出错，文件名：" + upLoadFile + "异常信息：" + ex.ToString ());
            } finally {
                if (uploadResponse != null)
                    uploadResponse.Close ();
                if (fileStream != null)
                    fileStream.Close ();
                if (requestStream != null)
                    requestStream.Close ();
            }
        }

        /// <summary>
        /// 从ftp下载文件到本地服务器
        /// </summary>
        /// <param name="downloadUrl">要下载的ftp文件路径，如/capture-2.avi</param>
        /// <param name="saveFileUrl">本地保存文件的路径，如(@"d:\capture-22.avi"</param>
        public void DownLoadFile (string downloadUrl, string saveFileUrl) {
            Stream responseStream = null;
            FileStream fileStream = null;
            StreamReader reader = null;

            try {
                FtpWebRequest downloadRequest = (FtpWebRequest) WebRequest.Create ("ftp://" + ftpHost + downloadUrl);
                downloadRequest.Method = WebRequestMethods.Ftp.DownloadFile;

                downloadRequest.Credentials = new NetworkCredential (ftpUser, ftpPassWord);

                FtpWebResponse downloadResponse = (FtpWebResponse) downloadRequest.GetResponse ();
                responseStream = downloadResponse.GetResponseStream ();

                fileStream = File.Create (saveFileUrl);
                byte[] buffer = new byte[1024];
                int bytesRead;
                while (true) {
                    bytesRead = responseStream.Read (buffer, 0, buffer.Length);
                    if (bytesRead == 0)
                        break;
                    fileStream.Write (buffer, 0, bytesRead);
                }
            } catch (Exception ex) {
                throw new Exception ("从ftp服务器下载文件出错，文件名：" + downloadUrl + "异常信息：" + ex.ToString ());
            } finally {
                if (reader != null) {
                    reader.Close ();
                }
                if (responseStream != null) {
                    responseStream.Close ();
                }
                if (fileStream != null) {
                    fileStream.Close ();
                }
            }
        }

        /// <summary>
        /// 从FTP下载文件到本地服务器,支持断点下载
        /// </summary>
        /// <param name="ftpUri">ftp文件路径，如"/test.txt"</param>
        /// <param name="saveFile">保存文件的路径，如C:\\test.txt</param>
        public void BreakPointDownLoadFile (string ftpUri, string saveFile) {
            System.IO.FileStream fs = null;
            System.Net.FtpWebResponse ftpRes = null;
            System.IO.Stream resStrm = null;
            try {
                Uri u = new Uri ("ftp://" + ftpHost + ftpUri);
                //设定下载文件的保存路径
                string downFile = saveFile;

                //FtpWebRequest的作成
                System.Net.FtpWebRequest ftpReq = (System.Net.FtpWebRequest)
                System.Net.WebRequest.Create (u);
                //设定用户名和密码
                ftpReq.Credentials = new System.Net.NetworkCredential (ftpUser, ftpPassWord);
                //MethodにWebRequestMethods.Ftp.DownloadFile("RETR")设定
                ftpReq.Method = System.Net.WebRequestMethods.Ftp.DownloadFile;
                //要求终了后关闭连接
                ftpReq.KeepAlive = false;
                //使用ASCII方式传送
                ftpReq.UseBinary = false;
                //设定PASSIVE方式无效
                ftpReq.UsePassive = false;

                //判断是否继续下载
                //继续写入下载文件的FileStream

                if (System.IO.File.Exists (downFile)) {
                    //继续下载
                    ftpReq.ContentOffset = (new System.IO.FileInfo (downFile)).Length;
                    fs = new System.IO.FileStream (
                        downFile, System.IO.FileMode.Append, System.IO.FileAccess.Write);
                } else {
                    //一般下载
                    fs = new System.IO.FileStream (
                        downFile, System.IO.FileMode.Create, System.IO.FileAccess.Write);
                }

                //取得FtpWebResponse
                ftpRes = (System.Net.FtpWebResponse) ftpReq.GetResponse ();
                //为了下载文件取得Stream
                resStrm = ftpRes.GetResponseStream ();
                //写入下载的数据
                byte[] buffer = new byte[1024];
                while (true) {
                    int readSize = resStrm.Read (buffer, 0, buffer.Length);
                    if (readSize == 0)
                        break;
                    fs.Write (buffer, 0, readSize);
                }
            } catch (Exception ex) {
                throw new Exception ("从ftp服务器下载文件出错，文件名：" + ftpUri + "异常信息：" + ex.ToString ());
            } finally {
                fs.Close ();
                resStrm.Close ();
                ftpRes.Close ();
            }
        }
    }

}